package com.leizi.igym.controller.admin;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leizi.igym.BaseContext.UserThreadLocal;
import com.leizi.igym.constant.JwtClaimsConstant;
import com.leizi.igym.constant.UserConstant;
import com.leizi.igym.domain.User;
import com.leizi.igym.dto.ModifyPasswordDTO;
import com.leizi.igym.dto.UserEditDTO;
import com.leizi.igym.dto.UserLoginDTO;
import com.leizi.igym.dto.UserPageQueryDTO;
import com.leizi.igym.enums.ReturnCodeEnum;
import com.leizi.igym.exception.BusinessException;
import com.leizi.igym.pojo.ContextUser;
import com.leizi.igym.properties.JWTProperties;
import com.leizi.igym.resp.PageResult;
import com.leizi.igym.resp.Result;
import com.leizi.igym.service.UserService;
import com.leizi.igym.utils.JwtUtil;
import com.leizi.igym.utils.ThrowUtils;
import com.leizi.igym.vo.UserLoginVO;
import com.leizi.igym.vo.UserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Objects;

/**
 * @Author: leizi0110
 * @CreateTime: 2024-03-30  21:08
 * @Description:
 */

@RestController("adminUserController")
@RequestMapping("/admin/user")
@Tag(name = "管理端-用户相关接口")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private JWTProperties jwtProperties;

    @Operation(summary = "管理端：管理员登录")
    @PostMapping("/login")
    public Result login(@RequestBody UserLoginDTO userLoginDTO) {
        log.info("管理员正在登录：{}", userLoginDTO);
        if (Objects.isNull(userLoginDTO)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        String account = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        if (StringUtils.isAnyBlank(account, password)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        User dbUser = userService.getOne(userService.getLoginQueryWrapper(account, password));
        if (Objects.isNull(dbUser)) {
            throw new BusinessException(ReturnCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }

        //  创建token
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.ADMIN_CLAIMS_ID, dbUser.getId());
        String token = JwtUtil.createJWT(jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);

        //  返回登录的vo
        UserLoginVO userLoginVO = UserLoginVO.builder().id(dbUser.getId())
                .avatar(dbUser.getAvatar())
                .username(dbUser.getUsername())
                .nickname(dbUser.getNickname())
                .roleId(dbUser.getRoleId())
                .token(token)
                .build();

        //  返回成功对象
        return Result.ok(userLoginVO);
    }

    @Operation(summary = "管理端：获取当前管理员信息")
    @GetMapping("info")
    public Result getInfo() {
        ContextUser contextUser = UserThreadLocal.get();
        log.info("管理端获取当前管理员信息，当前用户：{}", contextUser);
        if (Objects.isNull(contextUser)) {
            throw new BusinessException(ReturnCodeEnum.SYSTEM_ERROR);
        }
        User dbUser = userService.getById(contextUser.getId());
        if (Objects.isNull(dbUser)) {
            throw new BusinessException(ReturnCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        //  返回登录的vo
        UserLoginVO userLoginVO = UserLoginVO.builder().id(dbUser.getId())
                .avatar(dbUser.getAvatar())
                .username(dbUser.getUsername())
                .nickname(dbUser.getNickname())
                .build();
        return Result.ok(userLoginVO);
    }

    @Operation(summary = "管理端：注销登录")
    @PostMapping("logout")
    public Result logout() {
        ContextUser contextUser = UserThreadLocal.get();
        log.info("管理端注销登录，当前用户：{}", contextUser);
        UserThreadLocal.remove();
        return Result.ok();
    }

    @Operation(summary = "管理端：修改用户状态")
    @PutMapping("/{id}/{status}")
    public Result enableStatus(@PathVariable("id") Long id, @PathVariable("status") Integer status) {
        log.info("管理端正在修改用户状态，用户为：{}", id);

        // 校验用户id是否合法
        ThrowUtils.throwIf(Objects.isNull(id) || id < 0, ReturnCodeEnum.PARAMS_ERROR, "用户id有误！");

        // 检验状态值是否合法
        ThrowUtils.throwIf(Objects.isNull(status) ||
                        !UserConstant.USER_STATUS_LIST.contains(status)
                , ReturnCodeEnum.PARAMS_ERROR, "状态参数有误！");
        boolean result = userService.modifyStatus(id, status);
        return Result.ok(result);
    }

    @Operation(summary = "管理端：修改用户密码")
    @PutMapping("/{id}/password")
    public Result<Boolean> modifyPassword(@PathVariable("id") Long id,
                                          @RequestBody ModifyPasswordDTO dto) {
        log.info("管理端正在修改用户密码，用户id为：{}", id);
        // 检验id是否合法
        ThrowUtils.throwIf(Objects.isNull(id) || id <= 0, ReturnCodeEnum.PARAMS_ERROR);

        // 检验密码相关参数是否合法
        String originPassword = dto.getOldPassword();
        String newPassword = dto.getNewPassword();
        String checkPassword = dto.getCheckPassword();
        ThrowUtils.throwIf(StringUtils.isAnyBlank(originPassword,
                        newPassword,
                        checkPassword),
                ReturnCodeEnum.PARAMS_ERROR);
        ThrowUtils.throwIf(!newPassword.equals(checkPassword), ReturnCodeEnum.PARAMS_ERROR);
        boolean result = userService.updatePassword(id,
                originPassword,
                newPassword,
                checkPassword);
        return Result.ok(result);
    }

    @Operation(summary = "管理端：根据用户id查询用户信息")
    @GetMapping("/{id}")
    public Result<UserVO> getUserById(@PathVariable("id") Long id) {
        log.info("管理端正在根据用户id查询用户信息，用户id为：{}", id);
        // 检验id是否合法
        ThrowUtils.throwIf(Objects.isNull(id) || id <= 0, ReturnCodeEnum.PARAMS_ERROR);

        return Result.ok(userService.getUserById(id));
    }

    @Operation(summary = "管理端：分页查询用户信息")
    @PostMapping("/page")
    public Result<PageResult> getUserPage(@RequestBody UserPageQueryDTO dto) {
        log.info("管理端正在分页查询用户信息，分页参数为：{}", dto);
        // 检验分页对象是否合法
        ThrowUtils.throwIf(Objects.isNull(dto), ReturnCodeEnum.PARAMS_ERROR);

        long current = dto.getCurrent();
        long size = dto.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 50 || current <= 0 || size <= 0, ReturnCodeEnum.PARAMS_ERROR);

        Page<User> page = userService.page(new Page<>(current, size),
                userService.getUserPageQueryWrapper(dto));
        PageResult pageResult = PageResult.builder()
                .total(page.getTotal())
                .records(page.getRecords())
                .build();
        return Result.ok(pageResult);
    }

    @Operation(summary = "管理端：修改用户信息")
    @PutMapping("/edit/{id}")
    public Result modifyUserInAdmin(@PathVariable("id") Long id,
                                    @RequestBody UserEditDTO dto) {
        log.info("管理端正在修改用户信息，用户id为：{}，修改参数为：{}", id, dto);
        ThrowUtils.throwIf(ObjectUtils.anyNull(dto, id) || id <= 0 || !id.equals(dto.getId()),
                ReturnCodeEnum.PARAMS_ERROR);
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        return Result.ok(userService.editByIdInAdmin(user));
    }
}
